#include "ConcurrentAlloc.h"
#include <vector>
#include <thread>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <atomic>
#include <ctime>

using std::cout;
using std::endl;

void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime{0};
    std::atomic<size_t> free_costtime{0};

    for (size_t k = 0; k < nworks; ++k)
    {
        vthread[k] = std::thread([&, k] {
            std::vector<void*> v;
            v.reserve(ntimes);
            for (size_t j = 0; j < rounds; ++j)
            {
                size_t t1 = clock();
                for (size_t i = 0; i < ntimes; ++i) v.push_back(malloc(16));
                size_t t2 = clock();
                for (size_t i = 0; i < ntimes; ++i) free(v[i]);
                size_t t3 = clock();
                v.clear();
                malloc_costtime += (t2 - t1);
                free_costtime   += (t3 - t2);
            }
        });
    }
    for (auto& t : vthread) t.join();

    printf("[malloc] %zu 线程 × %zu 轮 × %zu 次/malloc：%zu ms\n",
           nworks, rounds, ntimes, malloc_costtime.load());
    printf("[malloc] %zu 线程 × %zu 轮 × %zu 次/free ：%zu ms\n",
           nworks, rounds, ntimes, free_costtime.load());
    printf("[malloc] 总 malloc+free %zu 次：%zu ms\n\n",
           nworks * rounds * ntimes,
           malloc_costtime.load() + free_costtime.load());
}

/* ---------- ConcurrentAlloc / ConcurrentFree ---------- */
void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime{0};
    std::atomic<size_t> free_costtime{0};

    for (size_t k = 0; k < nworks; ++k)
    {
        vthread[k] = std::thread([&] {
            std::vector<void*> v;
            v.reserve(ntimes);
            for (size_t j = 0; j < rounds; ++j)
            {
                size_t t1 = clock();
                for (size_t i = 0; i < ntimes; ++i) v.push_back(ConcurrentAlloc(16));
                size_t t2 = clock();
                for (size_t i = 0; i < ntimes; ++i) ConcurrentFree(v[i]);
                size_t t3 = clock();
                v.clear();
                malloc_costtime += (t2 - t1);
                free_costtime   += (t3 - t2);
            }
        });
    }
    for (auto& t : vthread) t.join();

    printf("[ConcurrentAlloc] %zu 线程 × %zu 轮 × %zu 次/alloc：%zu ms\n",
           nworks, rounds, ntimes, malloc_costtime.load());
    printf("[ConcurrentAlloc] %zu 线程 × %zu 轮 × %zu 次/free ：%zu ms\n",
           nworks, rounds, ntimes, free_costtime.load());
    printf("[ConcurrentAlloc] 总 alloc+free %zu 次：%zu ms\n\n",
           nworks * rounds * ntimes,
           malloc_costtime.load() + free_costtime.load());
}

